package org.xx.armory.security;

import org.xx.armory.commons.Verifiable;

import java.io.Serializable;
import java.util.Objects;

import static org.apache.commons.lang3.StringUtils.trimToEmpty;
import static org.apache.commons.text.StringEscapeUtils.escapeJson;
import static org.xx.armory.commons.Validators.notBlank;

/**
 * 角色。
 *
 * @author Haart
 */
public final class Role
        implements Verifiable, Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private final String name;

    private final String title;

    private final String description;

    private final boolean enabled;

    /**
     * 构造角色对象, 所有字段都是空白。
     */
    public Role() {
        this(null, null, null, true);
    }

    /**
     * 构造角色对象。
     *
     * @param name
     *         角色的名称, 会被正规化。
     * @param title
     *         角色的显示名称, 会被正规化。
     * @param description
     *         角色的描述, 会被正规化。
     * @param enabled
     *         角色是否启用。
     * @throws IllegalArgumentException
     *         如果参数{@code name}和{@code title}是{@code null}或者只包含空白字符。
     */
    public Role(
            String name,
            String title,
            String description,
            boolean enabled
    ) {
        this.name = notBlank(name, "name").trim();
        this.title = trimToEmpty(title);
        this.description = trimToEmpty(description);
        this.enabled = enabled;
    }

    /**
     * 获取角色名称。
     *
     * @return 角色名称。
     */
    public final String getName() {
        return this.name;
    }

    /**
     * 获取角色的显示名称。
     *
     * @return 角色的显示名称。
     */
    public final String getTitle() {
        return this.title;
    }

    /**
     * 获取角色的描述。
     *
     * @return 角色的描述。
     */
    public final String getDescription() {
        return this.description;
    }

    /**
     * 判断此角色是否可用。
     *
     * @return 此角色是否可用。
     */
    public final boolean isEnabled() {
        return this.enabled;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return Objects.hash(this.name, this.title);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof Role)) {
            return false;
        }
        final Role other = (Role) obj;
        if (this.name == null) {
            return other.name == null;
        } else {
            return this.name.equals(other.name);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "Role {" + "name:" + escapeJson(this.name) + ",title=" + escapeJson(this.title) + "}";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isValid() {
        return !this.title.isEmpty();
    }
}
